S01-14 JavaSE-异常处理
[TOC]
问题引入
java
public class Exception01 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
int res = num1 / num2; // 运行时抛出ArithmeticException
System.out.println("程序继续运行...."); // 不会执行
}
}解决方案-try-catch
java
package com.hspedu.exception_;
public class Exception01 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
try {
int res = num1 / num2; // 可能抛出异常的代码
} catch (Exception e) {
// 异常处理逻辑
System.out.println("出现异常的原因=" + e.getMessage());
}
System.out.println("程序继续运行...."); // 会执行
}
}异常介绍
基本概念
Java中,程序执行中的不正常情况称为异常(语法错误和逻辑错误不是异常)。
异常分类
- Error(错误):JVM无法解决的严重问题(如StackOverflowError、OOM),程序崩溃。
- Exception(异常):一般性问题,可通过代码处理,分为:
- 运行时异常(RuntimeException及其子类):编程逻辑错误,编译器不检查
- 编译时异常:编译器要求必须处理的异常
异常体系图
Serializable <- Object <- Throwable
/ \
/ \
Error Exception
/ / \
/ / \
StackOverflowError RuntimeException 编译时异常
/
/
NullPointerException、ArithmeticException、
ArrayIndexOutOfBoundsException、ClassCastException、
NumberFormatException常见的运行时异常
1) NullPointerException(空指针异常)
java
package com.hspedu.exception_;
public class NullPointerException_ {
public static void main(String[] args) {
String name = null;
System.out.println(name.length()); // 抛出空指针异常
}
}2) ArithmeticException(数学运算异常)
java
package com.hspedu.exception_;
public class ArithmeticException_ {
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
System.out.println(num1 / num2); // 抛出算术异常
}
}3) ArrayIndexOutOfBoundsException(数组下标越界异常)
java
package com.hspedu.exception_;
public class ArrayIndexOutOfBoundsException_ {
public static void main(String[] args) {
int[] arr = {1,2,4};
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]); // i=3时抛出异常
}
}
}4) ClassCastException(类型转换异常)
java
package com.hspedu.exception_;
public class ClassCastException_ {
public static void main(String[] args) {
A b = new B(); // 向上转型
C c2 = (C)b; // 向下转型失败,抛出类型转换异常
}
}
class A {}
class B extends A {}
class C extends A {}5) NumberFormatException(数字格式不正确异常)
java
package com.hspedu.exception_;
public class NumberFormatException_ {
public static void main(String[] args) {
String name = "韩顺平教育";
int num = Integer.parseInt(name); // 抛出数字格式异常
}
}编译异常
常见编译异常
- SQLException:数据库操作异常
- IOException:文件操作异常
- FileNotFoundException:文件未找到异常
- ClassNotFoundException:类未找到异常
- EOFException:文件末尾异常
- IllegalArgumentException:参数异常
案例演示
java
package com.hspedu.exception_;
import java.io.FileInputStream;
import java.io.IOException;
public class Exception02 {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("d:\\aa.jpg");
int len;
while ((len = fis.read()) != -1) {
System.out.println(len);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}异常处理方式
try-catch-finally:捕获异常,自行处理throws:抛出异常,由调用者处理
try-catch-finally 执行流程
java
try {
// 可能抛出异常的代码
} catch (异常类型 e) {
// 异常处理逻辑
} finally {
// 无论是否异常,都执行(释放资源)
}throws 处理流程
java
public static void 方法名() throws 异常类型 {
// 可能抛出异常的代码
}try-catch 异常处理
基本语法
java
try {
// 可疑代码
} catch (异常类型1 e) {
// 处理异常1
} catch (异常类型2 e) {
// 处理异常2
} finally {
// 释放资源
}注意事项
- 异常发生后,try块后续代码不执行,直接进入catch块
- 无异常时,不执行catch块
- 多个catch块时,子类异常在前,父类异常在后
- try-finally配合使用:不捕获异常,程序崩溃但finally仍执行
案例演示(TryCatchDetail.java)
java
package com.hspedu.try_;
public class TryCatchDetail {
public static void main(String[] args) {
try {
String str = "韩顺平";
int a = Integer.parseInt(str);
System.out.println("数字:" + a);
} catch (NumberFormatException e) {
System.out.println("异常信息=" + e.getMessage());
} finally {
System.out.println("finally 代码块被执行...");
}
System.out.println("程序继续...");
}
}多catch案例(TryCatchDetail02.java)
java
package com.hspedu.try_;
public class TryCatchDetail02 {
public static void main(String[] args) {
try {
Person person = new Person();
person = null;
System.out.println(person.getName()); // NullPointerException
int n1 = 10;
int n2 = 0;
int res = n1 / n2; // ArithmeticException
} catch (NullPointerException e) {
System.out.println("空指针异常=" + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("算术异常=" + e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class Person {
private String name = "jack";
public String getName() {
return name;
}
}throws 异常处理
基本语法
java
public static void readFile(String file) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("d://aa.txt");
}注意事项
- 编译异常必须处理(try-catch或throws)
- 运行时异常默认采用throws处理
- 子类重写父类方法时,抛出异常类型需与父类一致或为其子类
- 若方法内已try-catch处理异常,则无需throws
案例演示(ThrowsDetail.java)
java
package com.hspedu.throws_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ThrowsDetail {
public static void main(String[] args) {
f2();
}
public static void f2() {
// 运行时异常,默认throws处理
int n1 = 10;
int n2 = 0;
double res = n1 / n2;
}
public static void f1() throws FileNotFoundException {
// 编译异常,需throws或try-catch
f3();
}
public static void f3() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("d://aa.txt");
}
}
class Father {
public void method() throws RuntimeException {
}
}
class Son extends Father {
// 子类重写方法,抛出异常为父类异常的子类
@Override
public void method() throws ArithmeticException {
}
}自定义异常
步骤
- 定义类,继承Exception或RuntimeException
- 继承Exception:编译异常
- 继承RuntimeException:运行异常(推荐)
案例演示(CustomException.java)
java
package com.hspedu.customexception_;
public class CustomException {
public static void main(String[] args) {
int age = 180;
// 年龄不在18-120之间,抛出自定义异常
if (!(age >= 18 && age <= 120)) {
throw new AgeException("年龄需要在18~120 之间");
}
System.out.println("你的年龄范围正确.");
}
}
// 自定义运行时异常
class AgeException extends RuntimeException {
public AgeException(String message) {
super(message);
}
}throw 和 throws 的区别
| 特性 | throw | throws |
|---|---|---|
| 意义 | 手动生成异常对象 | 异常处理的一种方式 |
| 位置 | 方法体中 | 方法声明处 |
| 后面跟的内容 | 异常对象 | 异常类型 |